package des.wangku.operate.standard.task;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Spinner;

import des.wangku.operate.standard.dialog.RunDialog;
import des.wangku.operate.standard.dialog.ThreadRun;
import des.wangku.operate.standard.utls.UtilsList;
import des.wangku.operate.standard.utls.UtilsSWTComposite;
/**
 * 针对线程的抽像类
 * 
 * @author Sunjian
 * @version 1.0
 * @since jdk1.8
 */
public abstract class AbstractTask3_Thread extends AbstractTask2_CompositeExt implements InterfaceRunDialog,InterfaceMultiThreadOnRun{

	/** 运行时弹出的窗口 */
	public RunDialog ThreadRunDialog = null;

	/** 本父类对象 */
	protected AbstractTask3_Thread abstractTaskThread = this;
	/**
	 * 空的构造函数。如果调用此构造函数，则不初始化内部方法，只生成本Bean<br>
	 * 用于抽出项目class中的信息。无其它功能<br>
	 * 含 Composite 一个参数的构造函数必须存在，平台检索时需要此函数<br>
	 * @param parent Composite
	 */
	public AbstractTask3_Thread(Composite parent) {
		super(parent, SWT.NONE);
	}

	public AbstractTask3_Thread(Composite parent, int style) {
		super(parent, style);
	}

	/**
	 * 主窗体中的已经打开的单元，用于运行时暂时关闭单元，运行完成后，自动打开，已关闭的单元不在此列
	 */
	protected Control[] childrenControlThreadClose = {};

	/** 运行时暂时关闭，除关闭已经打开的单元外，可以额外控制(可以打开已经关闭的单元)，运行此方法前所有对象已关闭，可以额外打开 */
	//public abstract void multiThreadOnRun();

	/** 运行完成后打开有效性,除打开已经关闭的单元外。可以额外控制 */
	//public abstract void multiThreadOnRunEnd();

	/** 线程池 */
	//protected ThreadPoolExecutor ThreadPool =Executors.newFixedThreadPool(5);// Executors.newFixedThreadPool(10);
	protected ThreadPoolExecutor ThreadPool = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());

	/**
	 * 关闭运行对话框
	 */
	protected void ThreadRunDialogClose() {
		parentDisplay.asyncExec(new Runnable() {
			@Override
			public void run() {
				ThreadRunDialog.closeThread();
				ThreadRunDialog.getShell().dispose();
				for (int i = 0; i < childrenControlThreadClose.length; i++)
					childrenControlThreadClose[i].setEnabled(true);
				multiThreadOnRunEnd();
				//collect();
			}
		});
	}

	/**
	 * 中断线程
	 */
	protected void ThreadMainWorkThreadBreak() {
		ThreadPool.shutdown();
		ThreadRunDialogClose();
	}

	/**
	 * 得到线程池的状态，是否关闭
	 * @return boolean
	 */
	protected boolean getThreadMainWorkThreadState() {
		return ThreadPool.isTerminated();
	}

	/**
	 * 检测线程组状态线程，在运行线程组后启动此线程，
	 * 用于判断此线程组是否已经运行完成，如果运行完成
	 * 则关闭运行对话框
	 * @return Thread
	 */
	protected Thread getCommonThreadCheckGroup() {
		Thread threadCheckGroup = new Thread() {
			public void run() {
				while (!getThreadMainWorkThreadState()) {
					try {
						sleep(800);
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				ThreadRunDialogClose();
			}
		};
		return threadCheckGroup;
	}

	/**
	 * 父抽像类初始化
	 */
	void initialization() {
		super.initialization();
	}
	/**
	 * 弹出运行线程窗口
	 * @param max int
	 */
	protected void ThreadStart(int max) {
		parentDisplay.asyncExec(new Runnable() {
			public void run() {
				ThreadRunDialog = new RunDialog(parentComposite.getShell(), 0, abstractTaskThread, max);
				ThreadRunDialog.setThreadPool(ThreadPool);
				ThreadRunDialog.open();
			}
		});
	}

	/**
	 * 弹出运行线程窗口
	 * @param obj InterfaceRunDialog
	 * @param max int
	 */
	protected void ThreadStart(InterfaceRunDialog obj, int max) {
		parentDisplay.asyncExec(new Runnable() {
			public void run() {
				ThreadRunDialog = new RunDialog(parentComposite.getShell(), 0, obj, max);
				ThreadRunDialog.setThreadPool(ThreadPool);
				ThreadRunDialog.open();
			}
		});
	}

	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表 自定义线程数<br>
	 * 调取接口函数getECTFThreadRunUnitList
	 * @param spinner_maxthread Spinner
	 */
	protected void startECTFRunThread(Spinner spinner_maxthread) {
		Collection<InterfaceThreadRunUnit> workList = getECTFThreadRunUnitList();
		startECTFRunThread(workList, spinner_maxthread);
	}

	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表 自定义线程数
	 * @param workList Collection<InterfaceThreadRunUnit>
	 * @param spinner_maxthread Spinner
	 */
	protected void startECTFRunThread(Collection<InterfaceThreadRunUnit> workList, Spinner spinner_maxthread) {
		if (workList == null || workList.size() == 0) return;
		int selectNum = 1;
		if (spinner_maxthread != null) {
			selectNum = spinner_maxthread.getSelection();
			if (selectNum <= 0) selectNum = 2;
		}
		startECTFRunThread(workList, selectNum);
	}

	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表 list总数为线程数<br>
	 * 调取接口函数getECTFThreadRunUnitList
	 */
	protected void startECTFRunThread() {
		List<InterfaceThreadRunUnit> workList = getECTFThreadRunUnitList();
		startECTFRunThread(workList);
	}

	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表 指定线程数<br>
	 * 调取接口函数getECTFThreadRunUnitList
	 * @param threadNum int
	 */
	protected void startECTFRunThread(int threadNum) {
		List<InterfaceThreadRunUnit> workList = getECTFThreadRunUnitList();
		startECTFRunThread(workList, threadNum);
	}
	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表 list总数为线程数
	 * @param workList List<InterfaceThreadRunUnit>
	 */
	protected void startECTFRunThread(Collection<InterfaceThreadRunUnit> workList) {
		if (workList == null || workList.size() == 0) return;
		int selectNum = workList.size();
		startECTFRunThread(workList, selectNum);
	}

	/**
	 * 以线程池的形式运行 ExcelCTabFolder组件内部的信息列表
	 * @param workList Collection<InterfaceThreadRunUnit>
	 * @param selectNum int
	 */
	protected void startECTFRunThread(Collection<InterfaceThreadRunUnit> workList, int selectNum) {
		if (workList == null) return;
		int size = workList.size();
		if (size == 0) return;
		if (selectNum <= 0) selectNum = 2;
		int threadNum = UtilsList.getMaxThreadPoolCount(size, selectNum);
		if (threadNum > InterfaceMultiThreadOnRun.ACC_MAXThreadCount) threadNum = InterfaceMultiThreadOnRun.ACC_MAXThreadCount;
		List<InterfaceThreadRunUnit> newList = new ArrayList<>(size);
		for (InterfaceThreadRunUnit e : workList)
			newList.add(e);
		startECTFRunThreadWork(newList, threadNum);
	}

	/**
	 * -
	 * 以线程池的形式运行工作 ExcelCTabFolder组件组件内部的信息列表
	 * @param workList List<InterfaceThreadRunUnit>
	 * @param maxThreadNum int
	 */
	private final void startECTFRunThreadWork(List<InterfaceThreadRunUnit> workList, int maxThreadNum) {
		if (maxThreadNum <= 0) return;
		setIsBreakChange(false);
		allControlEnabledChange(false);
		multiThreadOnRun();
		ThreadStart(workList.size());
		//ThreadPool = Executors.newFixedThreadPool(maxThreadNum);
		ThreadPool = new ThreadPoolExecutor(maxThreadNum, maxThreadNum, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.CallerRunsPolicy());
		ThreadPool.allowCoreThreadTimeOut(true);

		List<List<InterfaceThreadRunUnit>> list2 = UtilsList.averageAssign(workList, maxThreadNum);
		for (int i = 0; i < maxThreadNum; i++) {
			Runnable task = new ThreadRun(abstractTaskThread, list2.get(i));
			ThreadPool.submit(task);
		}
		ThreadPool.shutdown();
		getCommonThreadCheckGroup().start();

	}

	/**
	 * 设置所有对象关闭或打开
	 * @param enabled boolean
	 */
	protected void allControlEnabledChange(boolean enabled) {
		childrenControlThreadClose = UtilsSWTComposite.getCompositeChildrenEnable(this, !enabled);
		for (int i = 0; i < childrenControlThreadClose.length; i++)
			childrenControlThreadClose[i].setEnabled(enabled);
	}
	/**
	 * 启动时调用
	 */
	public void startup_Load() {
		super.startup_Load();
	}
	/**
	 * 销毁时启动
	 */
	void disposeTask() {
		super.disposeTask();
	}

}
